home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
ppl4c10.zip
/
XYMODEM.C
< prev
next >
Wrap
Text File
|
1995-02-09
|
10KB
|
336 lines
/* xymodem.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "pcl4c.h"
#include "ascii.h"
#include "term_io.h"
#include "xypacket.h"
#include "xymodem.h"
#include "dir_io.h"
#include "timing.h"
#define ABORT_CHAR CAN
#define FALSE 0
#define TRUE !FALSE
static int DataBits = WordLength8;
static int StopBits = OneStopBit;
static int Parity = NoParity;
static void Set8N1(int Port)
{int PSL;
PSL = SioRead(Port,3);
DataBits = 0x03 & PSL;
StopBits = 0x01 & (PSL>>2);
Parity = 0x07 & (PSL>>3);
/* set 8N1 */
SioParms(Port,NoParity,OneStopBit,WordLength8);
}
static void RestorePSL(int Port)
{/* restore old setting */
SioParms(Port,Parity,StopBits,DataBits);
}
int TxyModem(
int Port, /* COM port [0..3] */
char *Filename, /* filename buffer */
char *Buffer, /* data buffer */
int OneKflag, /* if TRUE, use 1K blocks when possible */
int BatchFlag) /* if TRUE, send filename in packet 0 */
{int i, k;
int Code;
int Handle; /* file Handle */
long Tics;
char c;
int p;
char PacketType;
char PacketNbr;
int PacketSize = 128;
int FirstPacket;
unsigned short CheckSum;
int Number1K = 0; /* total # 1K packets */
int Number128 = 0; /* total # 128 byte packets */
char NCGchar = NAK;
long FileSize;
char Temp[81];
int EmptyFlag = FALSE;
/* begin */
Set8N1(Port);
if(BatchFlag) if(Filename[0]=='\0') EmptyFlag = TRUE;
if(!EmptyFlag)
{/* Filename is not empty */
EmptyFlag = FALSE;
Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
WriteMsg(Temp);
RestorePSL(Port);
return(FALSE);
}
}
WriteMsg("XYMODEM send: waiting for Receiver ");
while(SioKeyPress()) SioKeyRead();
/* compute # blocks */
if(!EmptyFlag)
{FileSize = filelength(Handle);
if(OneKflag) Number1K = (int) (FileSize / 1024L);
Number128 = (int) ((FileSize-1024L*(long)Number1K) / 128L);
if(128L*Number128+1024*Number1K < FileSize) Number128++;
sprintf(Temp,"%d 1024 & %d 128 byte packets",Number1K,Number128);
WriteMsg(Temp);
}
else
{/* empty file */
Number128 = 0;
Number1K = 0;
/*WriteMsg("Empty File");*/
}
/* clear comm port ( there may be several NAKs queued up ) */
SioRxFlush(Port);
/* get receivers start up NAK, 'C', or 'G' */
if(!TxStartup(Port,&NCGchar))
{RestorePSL(Port);
return(FALSE);
}
/* loop over all packets */
SioDelay(ONE_SECOND/4);
if(BatchFlag) FirstPacket = 0;
else FirstPacket = 1;
Tics = SioTimer();
for(p=FirstPacket;p<=Number1K+Number128;p++)
{/* user aborts ? */
if(SioKeyPress()) if((char)SioKeyRead()==ABORT_CHAR)
{TxCAN(Port);
WriteMsg("Aborted by USER");
RestorePSL(Port);
return(FALSE);
}
/* issue message */
sprintf(Temp,"Packet %d",p);
WriteMsg(Temp);
/* load up Buffer */
if(p==0)
{/* Filename packet ! */
PacketSize = 128;
k = 0;
for(i=0;i<strlen(Filename);i++) Buffer[k++] = Filename[i];
Buffer[k++] = '\0';
sprintf(Temp,"%ld",FileSize);
for(i=0;i<strlen(Temp);i++) Buffer[k++] = Temp[i];
while(k<128) Buffer[k++] = '\0';
}
else /* p > 0 */
{/* DATA Packet: use 1K or 128 byte block ? */
if(p<=Number1K) PacketSize = 1024;
else PacketSize = 128;
/* read next block from disk */
Code = read(Handle,Buffer,PacketSize);
if(Code<=0)
{SayError(Port,"Error on disk read");
RestorePSL(Port);
return(FALSE);
}
for(i=Code;i<PacketSize;i++) Buffer[i] = 0x1a;
}
/* send this packet */
if(!TxPacket(Port,p,PacketSize,Buffer,NCGchar))
{RestorePSL(Port);
return(FALSE);
}
/* must 'restart' after non null packet 0 */
if(!EmptyFlag&&(p==0)) TxStartup(Port,&NCGchar);
} /* end -- for(p) */
WriteCPS(Tics,FileSize,Filename,FALSE);
/* done if empty packet 0 */
if(EmptyFlag)
{WriteMsg("Batch transfer complete");
RestorePSL(Port);
return(TRUE);
}
/* all done. send EOT up to 10 times */
close(Handle);
if(!TxEOT(Port))
{SayError(Port,"EOT not acknowledged");
RestorePSL(Port);
return(FALSE);
}
WriteMsg("Transfer Complete");
RestorePSL(Port);
return(TRUE);
} /* end -- TxyModem */
int RxyModem(
int Port, /* COM port [0..3] */
char *Filename, /* filename buffer */
char *Buffer, /* data buffer */
char NCGparm, /* NAK, 'C', or 'G' */
int BatchFlag) /* if TRUE, get filename from packet 0 */
{int i;
int Handle; /* file Handle */
int p; /* packet index */
int Code; /* return code */
int FirstPacket;
char PacketNbr;
int PacketSize; /* 128 or 1024 */
long FileSize = 0;
long BytesRX = 0;
long BytesWanted;
char Temp[81];
long Tics;
int EOTflag = FALSE;
char NCGchar;
/* begin */
NCGchar = NCGparm;
Set8N1(Port);
EOTflag = FALSE;
WriteMsg("XYMODEM Receive: Waiting for Sender ");
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
SioRxFlush(Port);
/* Send NAKs, 'C's, or 'G's */
if(!RxStartup(Port,&NCGchar))
{RestorePSL(Port);
return(FALSE);
}
/* open file unless BatchFlag is on */
if(BatchFlag) FirstPacket = 0;
else
{/* start with packet 1 */
FirstPacket = 1;
/* open file passed in Filename[] for write */
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
WriteMsg(Temp);
RestorePSL(Port);
return(FALSE);
}
}
Tics = SioTimer();
/* get each packet in turn */
for(p=FirstPacket;;p++)
{/* user aborts ? */
if(SioKeyPress()) if((char)SioKeyRead()==ABORT_CHAR)
{TxCAN(Port);
RestorePSL(Port);
return(FALSE);
}
/* issue message */
sprintf(Temp,"Packet %d",p);
WriteMsg(Temp);
/* get next packet */
if(!RxPacket(Port,p,&PacketSize,Buffer,NCGchar,&EOTflag))
{RestorePSL(Port);
return(FALSE);
}
if(p==0)
{/* copy Filename */
strcpy(Filename,Buffer);
/* done if null packet 0 */
if(Filename[0]=='\0')
{WriteMsg("Batch Transfer Complete");
RestorePSL(Port);
return(TRUE);
}
}
BytesRX += (long)PacketSize;
/* all done if EOT was received */
if(EOTflag)
{
if(FileSize>0L) BytesRX = FileSize;
WriteCPS(Tics,BytesRX,Filename,FALSE);
close(Handle);
WriteMsg("Transfer Complete");
RestorePSL(Port);
return(TRUE);
}
/* process packet */
if(p==0)
{/* open file using filename in packet 0 */
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcat(Buffer," -- open failed");
WriteMsg(Buffer);
RestorePSL(Port);
return(FALSE);
}
/* get file length */
FileSize = atol(&Buffer[1+strlen(Buffer)]);
BytesWanted = FileSize;
/* must 'restart' after packet 0 */
RxStartup(Port,&NCGchar);
}
else /* DATA packet */
{/* write Buffer */
if(BatchFlag)
{if(BytesWanted<(long)PacketSize) i = (int) BytesWanted;
else i = PacketSize;
i = write(Handle,Buffer,i);
BytesWanted -= (long)i;
}
else write(Handle,Buffer,PacketSize);
} /* end -- else */
} /* end -- for(p) */
} /* end - RxyModem */
int TxCAN(int Port)
{int i;
for(i=0;i<6;i++) SioPutc(Port,CAN);
return(0);
}
/* XMODEM send */
void XmodemTx(int Port,char *FileName,char *Buffer,int OneKflag)
{if(!FetchName(FileName)) return;
TxyModem(Port,FileName,Buffer,OneKflag,FALSE);
}
/* XMODEM receive */
void XmodemRx(int Port,char *FileName,char *Buffer,char NCGchar)
{if(!FetchName(FileName)) return;
RxyModem(Port,FileName,Buffer,NCGchar,FALSE);
}
/* YMODEM send */
void YmodemTx(int Port,char *FileSpec,char *Buffer)
{char FileName[15];
if(!FetchName(FileSpec)) return;
if(FindFirst(FileSpec,FileName,NULL))
{TxyModem(Port,FileName,Buffer,TRUE,TRUE);
while(FindNext(FileName,NULL))
{SioDelay(1);
TxyModem(Port,FileName,Buffer,TRUE,TRUE);
}
}
/* send empty filename */
FileName[0] = '\0';
SioDelay(1);
TxyModem(Port,FileName,Buffer,TRUE,TRUE);
}
/* YMODEM receive */
void YmodemRx(int Port,char *Buffer,char NCGchar)
{char FileName[15];
do
{/* receive files till get empty filename */
RxyModem(Port,FileName,Buffer,NCGchar,TRUE);
if(SioKeyPress()) return;
} while(FileName[0]!='\0');
}